const express = require("express")
const app = express()
const joi = require("joi")
const path = require("path");
// 跨域
const cors = require("cors")
app.use(cors())

// 解析x-www-form-urlencoded 表单数据
app.use(express.urlencoded({ extended: false }))

// 如果下方模块需要调用该封装函数 则需要放在该函数下方 否则无法调用
// 封装res.cc函数
app.use((req, res, next) => {
    // status默认值为1，表示失败的情况
    // err的值 可能是一个错误对象 也可能是一个错误的描述字符串
    res.cc = function(err, status = 404) {
        res.send({
            status,
            // 如果err是错误对象则返回err.message 否则返回err字符串
            message: err instanceof Error ? err.message : err
        })
    }
    next()
})

// 导入秘钥
const config = require("./config")
    // 导入token中间件
const { expressjwt: expressJWT } = require("express-jwt")

// 一定要在路由之前配置解析token中间件
// 使用 unless指定哪些接口不需要token身份验证
app.use(expressJWT({ secret: config.jwtSecretKey, algorithms: ['HS256'] }).unless({ path: [/^\/api\//, /^\/html\/index.html/, /^\/html^\/login.html/, /^/] }))
app.use('/html', express.static(path.join(__dirname, 'html')));


// 导入并使用路由模块
const userRouter = require('./router/user')
app.use('/api', userRouter)
const userinfoRouter = require('./router/userinfo')

// 以/my开头的接口，都是有权限的接口 需要token认证
app.use('/my', userinfoRouter)
const artcateRouter = require('./router/artcate')
app.use('/my/article', artcateRouter)

const dateRouter = require('./router/date')
app.use('/api', dateRouter)
const instructorRouter = require('./router/instructor')
app.use('/my/instructor', instructorRouter)

// html页面
app.use(express.static(path.join(__dirname, 'html')));


// 定义错误级别的中间件
app.use((err, req, res, next) => {
    // 验证失败导致的错误
    if (err instanceof joi.ValidationError)
        return res.cc(err)
            //   身份验证失败的错误  
    if (err.name === 'UnauthorizedError') return res.cc('身份验证失败！')
        // 未知的错误
    res.cc(err)
})

app.listen(3007, () => {
    console.log("http://localhost:3007");
})